package com.auth.service.impl;

import com.auth.constant.MessageConstant;
import com.auth.pojo.dto.SecurityUserDTO;
import com.auth.result.CommonResult;
import com.tms.common.core.domain.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.tms.basicapi.api.BasicFeignClient;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理业务类
 * 适配 Spring Boot 3.x 和 Spring Security 6.x
 * 支持动态路由和菜单权限控制
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserDetailsService {

    private final PasswordEncoder passwordEncoder;

    private final BasicFeignClient basicFeignClient;

    // 定义admin用户名常量
    private static final String ADMIN_USERNAME = "admin";
    
    // 定义admin用户的所有权限列表，这里可以根据实际情况扩展
    private static final List<String> ADMIN_PERMISSIONS = Arrays.asList(
            "ROLE_ADMIN", 
            "system:*",
            "menu:*", 
            "user:*", 
            "role:*", 
            "order:*", 
            "transport:*", 
            "track:*", 
            "cost:*"
    );

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            // 远程调用基础微服务获取用户信息
            R result = basicFeignClient.getUserInfo(username);
            if (result == null || result.getData() == null) {
                throw new UsernameNotFoundException(MessageConstant.USERNAME_PASSWORD_ERROR);
            }
            
            // 获取用户数据
            Map<String, Object> userData = (Map<String, Object>) result.getData();
            
            // 判断用户是否存在
            if (userData == null || userData.get("id") == null) {
                throw new UsernameNotFoundException(MessageConstant.USERNAME_PASSWORD_ERROR);
            }

            // 创建安全用户对象
            SecurityUserDTO securityUser = createSecurityUser(userData, username);

            // 校验用户是否启用
            if (!securityUser.isEnabled()) {
                throw new DisabledException(MessageConstant.ACCOUNT_DISABLED);
            } else if (!securityUser.isAccountNonLocked()) {
                throw new LockedException(MessageConstant.ACCOUNT_LOCKED);
            } else if (!securityUser.isAccountNonExpired()) {
                throw new AccountExpiredException(MessageConstant.ACCOUNT_EXPIRED);
            } else if (!securityUser.isCredentialsNonExpired()) {
                throw new CredentialsExpiredException(MessageConstant.CREDENTIALS_EXPIRED);
            }
            return securityUser;
        } catch (Exception e) {
            log.error("认证失败: {}", e.getMessage(), e);
            throw new UsernameNotFoundException("认证失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 创建安全用户对象
     * 
     * @param userData 用户数据
     * @param username 用户名
     * @return 安全用户对象
     */
    private SecurityUserDTO createSecurityUser(Map<String, Object> userData, String username) {
        SecurityUserDTO securityUser = new SecurityUserDTO();
        
        // 设置基本信息
        securityUser.setId(Long.valueOf(userData.get("id").toString()));
        securityUser.setUsername(userData.get("username").toString());
        securityUser.setUserCode(userData.get("username").toString());
        
        // 处理密码
        String password = userData.get("password") != null ? userData.get("password").toString() : "";
        securityUser.setPassword(passwordEncoder.encode(password));
        
        // 处理状态
        Object statusObj = userData.get("status");
        boolean status = true;
        if (statusObj != null) {
            if (statusObj instanceof Boolean) {
                status = (Boolean) statusObj;
            } else if (statusObj instanceof Integer) {
                status = ((Integer) statusObj) == 1;
            } else if (statusObj instanceof String) {
                status = "1".equals(statusObj) || "true".equalsIgnoreCase((String) statusObj);
            }
        }
        securityUser.setEnabled(status);
        
        // 设置角色和菜单
        List<String> roles = new ArrayList<>();
        List<Map<String, Object>> menus = new ArrayList<>();
        
        // 如果是admin用户，设置所有权限
        if (ADMIN_USERNAME.equals(username)) {
            roles.addAll(ADMIN_PERMISSIONS);
            menus = createAdminMenus();
        } else {
            // 普通用户的角色和菜单处理
            // 这里可以根据userData中的信息来设置
        }
        
        // 设置角色和菜单
        securityUser.setAuthorities(roles.stream()
                .map(org.springframework.security.core.authority.SimpleGrantedAuthority::new)
                .toList());
        securityUser.setMenus(menus);
        
        return securityUser;
    }
    
    /**
     * 创建管理员菜单
     * 
     * @return 菜单列表
     */
    private List<Map<String, Object>> createAdminMenus() {
        List<Map<String, Object>> menus = new ArrayList<>();
        
        // 系统管理菜单
        Map<String, Object> systemMenu = createMenu(1L, "系统管理", "system", null, "system", "el-icon-setting", 1, 0L, 1);
        menus.add(systemMenu);
        
        // 用户管理子菜单
        Map<String, Object> userMenu = createMenu(2L, "用户管理", "user", "system/user/index", "user", "el-icon-user", 1, 1L, 1);
        menus.add(userMenu);
        
        // 角色管理子菜单
        Map<String, Object> roleMenu = createMenu(3L, "角色管理", "role", "system/role/index", "role", "el-icon-s-check", 1, 1L, 2);
        menus.add(roleMenu);
        
        // 菜单管理子菜单
        Map<String, Object> menuMenu = createMenu(4L, "菜单管理", "menu", "system/menu/index", "menu", "el-icon-menu", 1, 1L, 3);
        menus.add(menuMenu);
        
        // 运输管理菜单
        Map<String, Object> transportMenu = createMenu(5L, "运输管理", "transport", null, "transport", "el-icon-truck", 1, 0L, 2);
        menus.add(transportMenu);
        
        // 订单管理子菜单
        Map<String, Object> orderMenu = createMenu(6L, "订单管理", "order", "transport/order/index", "order", "el-icon-s-order", 1, 5L, 1);
        menus.add(orderMenu);
        
        // 轨迹管理子菜单
        Map<String, Object> trackMenu = createMenu(7L, "轨迹管理", "track", "transport/track/index", "track", "el-icon-map-location", 1, 5L, 2);
        menus.add(trackMenu);
        
        // 费用管理子菜单
        Map<String, Object> costMenu = createMenu(8L, "费用管理", "cost", "transport/cost/index", "cost", "el-icon-money", 1, 5L, 3);
        menus.add(costMenu);
        
        return menus;
    }
    
    /**
     * 创建菜单对象
     *
     * @param id 菜单ID
     * @param name 菜单名称
     * @param permission 权限标识
     * @param path 路由路径
     * @param component 组件路径
     * @param icon 图标
     * @param status 状态(0:禁用,1:正常)
     * @param parentId 父菜单ID
     * @param sort 排序
     * @return 菜单对象
     */
    private Map<String, Object> createMenu(Long id, String name, String permission, String path, 
                                         String component, String icon, Integer status, 
                                         Long parentId, Integer sort) {
        Map<String, Object> menu = new HashMap<>();
        menu.put("id", id);
        menu.put("name", name);
        menu.put("permission", permission);
        menu.put("path", path);
        menu.put("component", component);
        menu.put("icon", icon);
        menu.put("status", status);
        menu.put("parentId", parentId);
        menu.put("sort", sort);
        menu.put("type", path == null ? 0 : 1); // 0:目录 1:菜单 2:按钮
        return menu;
    }
}
